#include "buffer.h"
#include "common.h"

//CommonBCD
uint8_t CommonBCD::get(void)const
{
	return (v >> 4) * 10 + (v & 0xf);
}
void CommonBCD::set(uint8_t s)
{
	v = ((s / 10) << 4) + (s % 10);
}

//MMWeekBCD
uint8_t MMWeekBCD::month(void)const
{
	return ((mm >> 4) * 10) + (mm & 0xf);
}
uint8_t MMWeekBCD::week(void)const
{
	return ww;
}
void MMWeekBCD::month(uint8_t m)
{
	mm =  ((m / 10) << 4) + (m % 10);
}
void MMWeekBCD::week(uint8_t w)
{
	ww = w;
}

//CommonA01//ss:mm:hh DD-MM-WW-YY
CommonA01::CommonA01(const Calendar& c)
{
	(*this) = c;
}
string CommonA01::toStringU(void)const
{
	char buf[64] = {0};
	snprintf(buf, sizeof(buf), 
			"%02d-%02d-%02d %02d:%02d:%0d week[%d]", 
			year(), 
			month(), 
			day(), 
			hour(), 
			minute(),
			second(),
			week());
	return buf;
}
CommonA01& CommonA01::operator=(const Calendar& c)
{
	second(c.second());
	minute(c.minute());
	hour  (c.hour()  );
	day   (c.day()   );
	month (c.month() );
	week  (c.weekday());
	year  (c.year()%100);
}
uint8_t CommonA01::second	(void)const{return ss.get();}
uint8_t CommonA01::minute	(void)const{return mm.get();}
uint8_t CommonA01::hour		(void)const{return hh.get();}
uint8_t CommonA01::day		(void)const{return dd.get();}
uint8_t CommonA01::month	(void)const{return mw.month();}
uint8_t CommonA01::week		(void)const{return mw.week();}
uint8_t CommonA01::year		(void)const{return yy.get();}

void CommonA01::second	(uint8_t v){ss.set(v);}
void CommonA01::minute	(uint8_t v){mm.set(v);}
void CommonA01::hour	(uint8_t v){hh.set(v);}
void CommonA01::day		(uint8_t v){dd.set(v);}
void CommonA01::month	(uint8_t v){mw.month(v);}
void CommonA01::week	(uint8_t v){mw.week(v);}
void CommonA01::year	(uint8_t v){yy.set(v);}

//CommonA07//XXX.X=3.1
double CommonA07::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  ;
	return (v * double(0.1));
}
void CommonA07::set(const double d)
{
	uint32_t v = fabs(d * 10);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
}
CommonA07& CommonA07::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA07::CommonA07(const double d)
{
	(*this)=d;
}

//CommonA08//XXXX=4
double CommonA08::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  ;
	return (v * double(1));
}
void CommonA08::set(const double d)
{
	uint32_t v = fabs(d * 1);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
}
CommonA08& CommonA08::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA08::CommonA08(const double d)
{
	(*this)=d;
}

//CommonA10//XXXXXX=6
double CommonA10::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 100 * 100
	  ;
	return (v * double(1));
}
void CommonA10::set(const double d)
{
	uint32_t v = fabs(d * 1);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
}
CommonA10& CommonA10::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA10::CommonA10(const double d)
{
	(*this)=d;
}

//CommonA11//XXXX.XX=4.2
double CommonA11::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 100 * 100
	  ;
	return (v * double(0.01));
}
void CommonA11::set(const double d)
{
	uint32_t v = fabs(d * 100);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
}
CommonA11& CommonA11::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA11::CommonA11(const double d)
{
	(*this) = d;
}

//CommonA12//XXXXXXXXXXXX=12
double CommonA12::get(void)
{
	uint64_t v = 0ULL;

	v = aa.get()
	  + bb.get() * 100ULL
	  + cc.get() * 10000ULL
	  + dd.get() * 1000000ULL
	  + ee.get() * 100000000ULL
	  + ff.get() * 10000000000ULL
	  ;
	return (v * double(1));
}
void CommonA12::set(const double d)
{
	uint64_t v = fabs(d * 1);

	aa.set((v / 1ULL) % 100ULL);
	bb.set((v / 100ULL) % 100ULL);
	cc.set((v / 10000ULL) % 100ULL);
	dd.set((v / 1000000ULL) % 100ULL);
	ee.set((v / 100000000ULL) % 100ULL);
	ff.set((v / 10000000000ULL) % 100ULL);
}
CommonA12& CommonA12::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA12::CommonA12(const double d)
{
	(*this) = d;
}

//CommonA13//XXXX.XXXX=4.4
double CommonA13::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 100 * 100
	  + dd.get() * 100 * 100 * 100
	  ;
	return (v * double(0.01));
}
void CommonA13::set(const double d)
{
	uint32_t v = fabs(d * 10000);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
	dd.set((v / 1000000) % 100);
}
CommonA13& CommonA13::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA13::CommonA13(const double d)
{
	(*this)=d;
}

//CommonA14//XXXXXX.XXXX=6.5
double CommonA14::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 100 * 100
	  + dd.get() * 100 * 100 * 100
	  + ee.get() * 100 * 100 * 100 * 100
	  ;
	return (v * double(0.0001));
}
void CommonA14::set(const double d)
{
	uint32_t v = fabs(d * 10000);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
	dd.set((v / 1000000) % 100);
	ee.set((v / 100000000) % 100);
}
CommonA14& CommonA14::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA14::CommonA14(const double d)
{
	(*this) = d;
}

//CommonA15//mm:hh DD-MM-YY
CommonA15& CommonA15::operator=(const string& s)
{
	*this = Calendar("%y-%m-%d %H:%M", s);
	return *this;
}
CommonA15& CommonA15::operator=(const Calendar& c)
{
	minute(c.minute());
	hour(c.hour());
	day(c.day());
	month(c.month());
	year(c.year()%100);
	return *this;
}
CommonA15::CommonA15(const Calendar& c)
{
	(*this)=c;
}
string CommonA15::toStringU(void)const
{
	char buf[32] = {0};
	snprintf(buf, sizeof(buf), "%02d-%02d-%02d %02d:%02d:--", 
			year(), month(), day(), hour(), minute());
	return buf;
}
uint8_t CommonA15::minute	(void)const{return mm.get();}
uint8_t CommonA15::hour		(void)const{return hh.get();}
uint8_t CommonA15::day		(void)const{return DD.get();}
uint8_t CommonA15::month	(void)const{return MM.get();}
uint8_t CommonA15::year	(void)const{return YY.get();}
void CommonA15::minute	(uint8_t v){mm.set(v);}
void CommonA15::hour	(uint8_t v){hh.set(v);}
void CommonA15::day		(uint8_t v){DD.set(v);}
void CommonA15::month	(uint8_t v){MM.set(v);}
void CommonA15::year	(uint8_t v){YY.set(v);}

//CommonA16//mm:hh DD-MM
CommonA16& CommonA16::operator=(const Calendar& c)
{
	second(c.second());
	minute(c.minute());
	hour(c.hour());
	day(c.day());
	return *this;
}
CommonA16::CommonA16(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA16::second	(void)const{return ss.get();}
uint8_t CommonA16::minute	(void)const{return mm.get();}
uint8_t CommonA16::hour		(void)const{return hh.get();}
uint8_t CommonA16::day		(void)const{return DD.get();}
void CommonA16::second  (uint8_t v){ss.set(v);}
void CommonA16::minute	(uint8_t v){mm.set(v);}
void CommonA16::hour	(uint8_t v){hh.set(v);}
void CommonA16::day		(uint8_t v){DD.set(v);}

//CommonA17//mm:hh DD-MM
CommonA17& CommonA17::operator=(const Calendar& c)
{
	minute(c.minute());
	hour(c.hour());
	day(c.day());
	month(c.month());
	return *this;
}
CommonA17::CommonA17(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA17::minute	(void)const{return mm.get();}
uint8_t CommonA17::hour		(void)const{return hh.get();}
uint8_t CommonA17::day		(void)const{return DD.get();}
uint8_t CommonA17::month	(void)const{return MM.get();}
void CommonA17::minute	(uint8_t v){mm.set(v);}
void CommonA17::hour	(uint8_t v){hh.set(v);}
void CommonA17::day		(uint8_t v){DD.set(v);}
void CommonA17::month	(uint8_t v){MM.set(v);}

//CommonA18//mm:hh DD
CommonA18& CommonA18::operator=(const Calendar& c)
{
	minute(c.minute());
	hour(c.hour());
	day(c.day());
	return *this;
}
CommonA18::CommonA18(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA18::minute	(void)const{return mm.get();}
uint8_t CommonA18::hour		(void)const{return hh.get();}
uint8_t CommonA18::day		(void)const{return DD.get();}
void CommonA18::minute	(uint8_t v){mm.set(v);}
void CommonA18::hour	(uint8_t v){hh.set(v);}
void CommonA18::day		(uint8_t v){DD.set(v);}

//CommonA19//mm:hh
CommonA19& CommonA19::operator=(const Calendar& c)
{
	minute(c.minute());
	hour(c.hour());
	return *this;
}
CommonA19::CommonA19(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA19::minute	(void)const{return mm.get();}
uint8_t CommonA19::hour		(void)const{return hh.get();}
void CommonA19::minute	(uint8_t v){mm.set(v);}
void CommonA19::hour	(uint8_t v){hh.set(v);}

//CommonA20//DD-MM-YY
CommonA20& CommonA20::operator=(const string& s)
{
	*this = Calendar("%y-%m-%d", s);
	return *this;
}
CommonA20& CommonA20::operator=(const Calendar& c)
{
	day(c.day());
	month(c.month());
	year(c.year()%100);
	return *this;
}
CommonA20::CommonA20(const Calendar& c)
{
	(*this)=c;
}
string CommonA20::toStringU(void)const
{
	char buf[32];
	snprintf(buf, sizeof(buf), "%02d-%02d-%02d", year(), month(), day());
	return buf;
}
uint8_t CommonA20::day		(void)const{return DD.get();}
uint8_t CommonA20::month	(void)const{return MM.get();}
uint8_t CommonA20::year		(void)const{return YY.get();}
void CommonA20::day		(uint8_t v){DD.set(v);}
void CommonA20::month	(uint8_t v){MM.set(v);}
void CommonA20::year	(uint8_t v){YY.set(v);}

//CommonA21//MM-YY
CommonA21& CommonA21::operator=(const Calendar& c)
{
	month(c.month());
	year(c.year()%100);
	return *this;
}
CommonA21::CommonA21(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA21::month	(void)const{return MM.get();}
uint8_t CommonA21::year		(void)const{return YY.get();}
void CommonA21::month	(uint8_t v){MM.set(v);}
void CommonA21::year	(uint8_t v){YY.set(v);}

//CommonA22//X.X=1.1
double CommonA22::get(void)
{
	uint32_t v = 0;

	v = aa.get();

	return (v * double(0.1));
}
void CommonA22::set(const double d)
{
	uint32_t v = fabs(d * 10);

	aa.set((v / 1) % 100);
}
CommonA22& CommonA22::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA22::CommonA22(const double d)
{
	(*this)=d;
}

//CommonA23//XX.XXXX=2.4
CommonA23& CommonA23::operator=(const double d)
{
	set(d); 
	return *this;
}
CommonA23::CommonA23(const double d)
{
	(*this) = d;
}
double CommonA23::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 100 * 100
	  ;
	return (v * double(0.0001));
}
void CommonA23::set(const double d)
{
	uint32_t v = fabs(d * 10000);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
}

//CommonA24//hh DD
CommonA24& CommonA24::operator=(const Calendar& c)
{
	hour(c.hour());
	day(c.day());
	return *this;
}
CommonA24::CommonA24(const Calendar& c)
{
	(*this)=c;
}
uint8_t CommonA24::hour		(void)const{return hh.get();}
uint8_t CommonA24::day		(void)const{return DD.get();}
void CommonA24::hour	(uint8_t v){hh.set(v);}
void CommonA24::day		(uint8_t v){DD.set(v);}

//CommonA26//X.XXX=1.3
CommonA26::CommonA26(const double d)
{
	(*this)=d;
}
CommonA26& CommonA26::operator=(const double d)
{
	set(d); 
	return *this;
}
void CommonA26::set(const double d)
{
	uint32_t v = fabs(d * 1000);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
}
double CommonA26::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  ;
	return (v * double(0.001));
}

//CommonA27//XXXXXXXX=8
CommonA27::CommonA27(const double d)
{
	(*this)=d;
}
CommonA27& CommonA27::operator=(const double d)
{
	set(d); 
	return *this;
}
void CommonA27::set(const double d)
{
	uint32_t v = fabs(d * 1);

	aa.set((v / 1) % 100);
	bb.set((v / 100) % 100);
	cc.set((v / 10000) % 100);
	dd.set((v / 1000000) % 100);
}
double CommonA27::get(void)
{
	uint32_t v = 0;

	v = aa.get()
	  + bb.get() * 100
	  + cc.get() * 10000
	  + dd.get() * 1000000
	  ;
	return (v * double(1));
}

//DataType
DataType::DataType(uint8_t fn, uint16_t pn)
{
	Fn(fn);
	Pn(pn);
}
DataType& DataType::operator=(uint32_t pnfn)
{
	Pn(pnfn>>8);
	Fn(0xFF&pnfn);
	return *this;
}
DataType::operator int(void)const
{
	return (Fn() << 16) + Pn();
}
bool DataType::append(class Buffer& b)
{
	return b.append(this, sizeof(*this));
}
string DataType::toStringU(void)const
{
	char buf[32] = {0};
	snprintf(buf, sizeof(buf), "[F%d, P%d]", Fn(), Pn());
	return buf;
}
void DataType::Pn(uint16_t n)
{
	switch(n)
	{
	case 0x0000:
		_DA1 = 0;
		_DA2 = 0;
		return;
	case 0xffff:
		_DA1 = 0xFF;
		_DA2 = 0x00;
		return;
	}
	n = n - 1;
	_DA1 = 1 << (n % 8);
	_DA2 = 1  + (n / 8);
}
void DataType::Fn(uint8_t n)
{
	if(n >= FN_MIN && n <= FN_MAX)
	{
		n = n - 1;
		_DT1 = 1 << (n % 8);
		_DT2 = 0  + (n / 8);
	}
}
uint16_t DataType::Pn(void)const
{
	if(_DA2 < 1)
	{
		return (_DA1 == 0xFF) ? 0xFF00 : 0;
	}
	switch(_DA1)
	{
		case (1<<0): return (_DA2 - 1) * 8 + 1;
		case (1<<1): return (_DA2 - 1) * 8 + 2;
		case (1<<2): return (_DA2 - 1) * 8 + 3;
		case (1<<3): return (_DA2 - 1) * 8 + 4;
		case (1<<4): return (_DA2 - 1) * 8 + 5;
		case (1<<5): return (_DA2 - 1) * 8 + 6;
		case (1<<6): return (_DA2 - 1) * 8 + 7;
		case (1<<7): return (_DA2 - 1) * 8 + 8;
	}
	return 0;
}
uint8_t  DataType::Fn(void)const
{
	switch(_DT1)
	{
		case (1<<0): return (_DT2 * 8) + 1;
		case (1<<1): return (_DT2 * 8) + 2;
		case (1<<2): return (_DT2 * 8) + 3;
		case (1<<3): return (_DT2 * 8) + 4;
		case (1<<4): return (_DT2 * 8) + 5;
		case (1<<5): return (_DT2 * 8) + 6;
		case (1<<6): return (_DT2 * 8) + 7;
		case (1<<7): return (_DT2 * 8) + 8;
	}
	return 0;
}

//Password
Password& Password::operator=(const string& s)
{
	uint8_t *p = (uint8_t*)s.data();
	for(int i = 0;  p && i < sizeof(pw); i++)
	{
		pw[i] = p[i];
	}
}
bool Password::append(class Buffer& b)
{
	return b.append(this, sizeof(*this));
}

//ErrorCounter
bool ErrorCounter::append(class Buffer& b)
{
	return b.append(this, sizeof(*this));
}
//AUXTime
bool AUXTime::append(class Buffer& b)
{
	return b.append(this, sizeof(*this));
}

